import { ChangeCase, defineConfig, Interface } from 'yapi-to-typescript';
import { mkdir } from 'shelljs';
//@ts-ignore
import { findIndex, map, remove, groupBy, upperFirst } from 'lodash';

import fs from 'fs';

import {
  genApiInterfaceName,
  generateApi,
  generateApiFunction,
  generateColumnSchemaFunction,
  generateShortPath,
  handleBaseRootPath,
  IParameters,
  parseParamsPath,
} from './src/utils/interface';
import { formatCode } from './src/utils/prettify';
import { md5 } from './src/utils/utils';
import { getRequestName } from './src/utils/name';
import { config } from './src/config';
import path from 'path';

let param: Array<IParameters> = [];
const cacheFile = '_cache_file.ts';
if (fs.existsSync(cacheFile)) {
  param = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
}
const stopArr: { path: string; title: string }[] = [];
//@ts-ignore
global.globalMap = new Map();

export default defineConfig(
  [
    {
      serverUrl: 'http://localhost:40001',
      typesOnly: true,
      target: 'typescript',
      reactHooks: {
        enabled: false,
      },
      prodEnvName: 'local',
      outputFilePath: (interfaceInfo: Interface, changeCase: ChangeCase) => {
        const path = parseParamsPath(interfaceInfo).split('/');
        const filePath = path.map((item) => changeCase.camelCase(item)).join('/');
        return `${config.typepath}${filePath}.ts`;
      },
      preproccessInterface: (interfaceInfo: Interface): Interface | false => {
        if (interfaceInfo.status != 'done') {
          return false;
        }
        const sign = md5(interfaceInfo.method + '-' + handleBaseRootPath(interfaceInfo));

        //已经生成的文件
        const inx = findIndex(param, (item: IParameters) => item.sign == sign);
        if (inx != -1) {
          if (interfaceInfo.up_time == param[inx].up_time) {
            return false;
          } else {
            //需要检测变动的参数
            const arrMaps: Map<string, string> = new Map([
              ['method', '请求方法:'],
              ['path', '请求地址:'],
              ['req_params', 'params参数:'],
              ['req_params', 'params参数:'],
              ['req_query', 'query参数:'],
              ['req_body_form', 'body_form参数:'],
              ['res_body', 'res_body参数:'],
              ['req_body_other', 'body_other参数:'],
            ]);
            console.info('有变动的接口名称:', interfaceInfo.title);
            arrMaps.forEach((value, key: string) => {
              if (param[inx].interfaceInfo[key] != interfaceInfo[key]) {
                console.info(
                  value,
                  '源:',
                  param[inx].interfaceInfo[key],
                  '变更后:',
                  interfaceInfo[key],
                );
              }
            });
            console.info('===============');
          }
          //判断是否已停用
          if (interfaceInfo.status != 'done') {
            remove(param, 'sign');
            stopArr.push({ path: interfaceInfo.path, title: interfaceInfo.title });
            return false;
          }
          return false;
        } else {
          //接口是未完成的情况,不生成
          if (interfaceInfo.status == 'undone') {
            return false;
          }
        }
        //
        const fullpath = parseParamsPath(interfaceInfo);
        param.push({
          sign: sign,
          catid: interfaceInfo.catid,
          path: fullpath,
          shortpath: generateShortPath(fullpath),
          interfaceInfo: interfaceInfo,
          up_time: interfaceInfo.up_time,
        });

        return interfaceInfo;
      },
      // 生成ts文件中请求参数interface名称,将下划线命名转换成pascal命名
      getRequestDataTypeName: (interfaceInfo: Interface) => {
        return getRequestName(interfaceInfo);
      },
      // 生成ts文件中请求响应数据interface名称,将下划线命名转换成pascal命名
      getResponseDataTypeName: (interfaceInfo: Interface) => {
        let query = '';
        if (interfaceInfo.req_params.length > 0) {
          query = 'Raw';
        }
        const method = interfaceInfo.method.toLowerCase();
        return (
          'I' + upperFirst(method) + query + genApiInterfaceName(interfaceInfo, true, 'Response')
        );
      },

      comment: {
        enabled: false,
      },
      jsonSchema: {
        enabled: true,
      },
      dataKey: 'result',
      projects: [
        {
          token: config.token,
          categories: [
            {
              id: 0,
            },
          ],
        },
      ],
    },
  ],
  {
    success: () => {
      //fs.writeFileSync(cacheFile, JSON.stringify(param));

      const arr = groupBy(param, 'catid');

      map(arr, (itemArr: IParameters[]) => {
        const groupItems = groupBy(itemArr, 'shortpath');
        map(groupItems, (items: IParameters[], pkgpath: string) => {
          let bodycontent = '\r\n';
          let columnStr = '';
          const pkgStr = generateApi(items);

          map(items, (item: IParameters) => {
            bodycontent += generateApiFunction(item.interfaceInfo);
            //
            columnStr += generateColumnSchemaFunction(item.interfaceInfo);
          });
          const tempPath = `${config.apipath}${pkgpath}`;
          const filepath = path.resolve(tempPath);
          const filename = path.basename(tempPath);

          const str = pkgStr + '\r\n' + bodycontent;

          if (!fs.existsSync(path.resolve(filepath))) {
            mkdir('-p', path.resolve(filepath));
          }

          formatCode(str).then((res) => {
            const apipath = `${filepath}/${filename}.api.ts`;
            if (!fs.existsSync(apipath)) {
              fs.writeFileSync(apipath, res);
            }
          });
          // //生成列表、搜索、表单数据
          if (columnStr != '') {
            const str =
              `import { BasicColumn,FormSchema} from '/@/components/Table';\r\n` + columnStr;
            formatCode(str).then((res) => {
              const datapath = `${filepath}/${filename}.data.ts`;
              if (!fs.existsSync(datapath)) {
                fs.writeFileSync(datapath, res);
              }
            });
          }
        });
      });
    },
  },
);
